package com.medplus.hubdirect.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.medplus.hubdirect.model.User;
import com.medplus.hubdirect.model.UserEndPoint;


@Repository("userEndPointDAO")
public class UserEndPointDAOImpl implements UserEndPointDAO {

    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    public void setEntityManagerFactory(
            EntityManagerFactory entityManagerFactory) {
        this.entityManagerFactory = entityManagerFactory;
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public User findUserById(long id) {
    	return entityManager.find(User.class, id);
    }
    
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public User findUser(String name) {
    	Query query = entityManager.createNamedQuery("findUserByName");
    	query.setParameter("name", name);
    	return (User) query.getSingleResult();
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public List<User> findUsers() {
    	Query query = entityManager.createNamedQuery("findUsers");
    	return query.getResultList();
    }
    
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public UserEndPoint findUserEndPoint(String userName, String endpoint) {
    	Query query = entityManager.createNamedQuery("findUserEndPointByName");
    	query.setParameter("name", userName);
    	query.setParameter("point", endpoint);
    	return (UserEndPoint) query.getSingleResult();
    }
    
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public User save(User user) {
        return entityManager.merge(user);
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void delete(User user) {
    	// you have to find the user entity first
    	User userEntity = findUser(user.getUserName());  
    	entityManager.remove(entityManager.merge(userEntity));
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public User addEndPointToUser(UserEndPoint endpoint) {
        User user = endpoint.getUser();

        if (user.getEndpoints().contains(endpoint)) {
        	user.getEndpoints().remove(endpoint);
        }

        user.getEndpoints().add(endpoint);        

        return save(user);
    }
    
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public User deleteEndPointFromUser(UserEndPoint endpoint) {
    	User user = endpoint.getUser();

        for (UserEndPoint pt : user.getEndpoints()) {
            if (pt.getEndPoint().equals(endpoint.getEndPoint()) && 
            		pt.getUserName().equals(endpoint.getUserName())) {
                entityManager.remove(entityManager.merge(pt));
                user.getEndpoints().remove(pt);                    
                break;
            }
        }

        return user;
    }
    
    
}
